#include "bsp_can.h"
#include "bsp_led.h"
#include "bsp_timer.h"

stc_can_rxframe_t   stcRxFrame;
stc_can_txframe_t   TxFrame_Gain;
stc_can_txframe_t   TxFrame_Keepalive;

stc_can_t APP_CAN;

en_ACC_Status ACC_Status = Off;

extern void PWM_duty_adjust(uint16_t adc_value, uint16_t MAX_Value); 

static void Can_Gpio_Init(void)
{
    stc_gpio_cfg_t stcGpioCfg;

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);

    ///< 端口方向配置->输入
    stcGpioCfg.enDir = GpioDirIn;
    ///< 端口驱动能力配置->高驱动能力
    stcGpioCfg.enDrv = GpioDrvL;
    ///< 端口上下拉配置->无
    stcGpioCfg.enPu = GpioPuDisable;
    stcGpioCfg.enPd = GpioPdDisable;
    ///< 端口开漏输出配置->开漏输出关闭
    stcGpioCfg.enOD = GpioOdDisable;
    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    stcGpioCfg.enCtrlMode = GpioAHB;

    Gpio_Init(EVB_CAN_RX_PORT, EVB_CAN_RX_PIN, &stcGpioCfg);
    stcGpioCfg.enDir = GpioDirOut;
    Gpio_Init(EVB_CAN_TX_PORT, EVB_CAN_TX_PIN, &stcGpioCfg);
    Gpio_Init(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN, &stcGpioCfg);

    ///<CAN RX\TX复用功能配置
    Gpio_SetAfMode(EVB_CAN_RX_PORT, EVB_CAN_RX_PIN, GpioAf3);
    Gpio_SetAfMode(EVB_CAN_TX_PORT, EVB_CAN_TX_PIN, GpioAf5);

    ///<STB 低-PHY有效
    Gpio_ClrIO(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN);
}


#ifdef CAN_CHIP_TJA1043

/*
TJA1043 刚上电是出于激活状态的,如果CAN总线没有数据,30s左右会休眠
3个IO需要配置:
IO_ERR 检测总线出错标志(可以忽略)
IO_EN 芯片使能
IO_INH 使能外部LDO +5V
IO_STB_N standby模式使能
*/
static void TJA1043_Gpio_Init(void)
{
    stc_gpio_cfg_t stcGpioCfg;

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);

    ///< 端口方向配置->输出
    stcGpioCfg.enDir = GpioDirOut;
    ///< 端口驱动能力配置->高驱动能力
    stcGpioCfg.enDrv = GpioDrvH;
    ///< 端口上下拉配置->无
    stcGpioCfg.enPu = GpioPuDisable;
    stcGpioCfg.enPd = GpioPdDisable;
    ///< 端口开漏输出配置->开漏输出关闭
    stcGpioCfg.enOD = GpioOdDisable;
    ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    stcGpioCfg.enCtrlMode = GpioAHB;
	
    Gpio_Init(GpioPortA, GpioPin3, &stcGpioCfg); // STB_N
    Gpio_Init(GpioPortB, GpioPin3, &stcGpioCfg); //IO_INH  
    Gpio_Init(GpioPortB, GpioPin7, &stcGpioCfg); // IO_EN
	
	Gpio_ClrIO(GpioPortB, GpioPin3);  /* PB3 IO_INH*/
	delay1ms(10); 
    Gpio_SetIO(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN);
	Gpio_SetIO(GpioPortB, GpioPin7);// IO_EN
	
}


void TJA1043_Goto_Sleep(void)
{
	Gpio_ClrIO(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN);
	Gpio_SetIO(GpioPortB, GpioPin7);// IO_EN
}

#endif

void BSP_Can_Init(void)
{
    stc_can_init_config_t   stcCanInitCfg;
    stc_can_filter_t        stcFilter;

	Can_Gpio_Init();

#ifdef CAN_CHIP_TJA1043
	TJA1043_Gpio_Init();	
#endif
	
    Sysctrl_SetPeripheralGate(SysctrlPeripheralCan, TRUE);
    //<<CAN 波特率配置
	// 手册page884.exp: bt = (PRESC+1)((SEG_1+2) + (SEG_2+1))*(1/8M) = 1us (1000k)

#ifdef CAN_CONFIG_48MHZ_500K	 
	
	stcCanInitCfg.stcCanBt.PRESC = 6-1;
	stcCanInitCfg.stcCanBt.SEG_1 = 9-2;
	stcCanInitCfg.stcCanBt.SEG_2 = 7-1;	
	stcCanInitCfg.stcCanBt.SJW   = 3-1;	
	
//	stcCanInitCfg.stcCanBt.PRESC = 8-1;
//  stcCanInitCfg.stcCanBt.SEG_1 = 7-2;
//  stcCanInitCfg.stcCanBt.SEG_2 = 5-1;
//  stcCanInitCfg.stcCanBt.SJW   = 5-1;
	
#endif

    stcCanInitCfg.stcWarningLimit.CanErrorWarningLimitVal = 10;
    stcCanInitCfg.stcWarningLimit.CanWarningLimitVal = 16-1;

    stcCanInitCfg.enCanRxBufAll  = CanRxNormal;
    stcCanInitCfg.enCanRxBufMode = CanRxBufNotStored;
    stcCanInitCfg.enCanSTBMode   = CanSTBFifoMode;

    CAN_Init(&stcCanInitCfg);

    //<<CAN 滤波器配置 /*u32MASK = 0x1FFFFFFF is all received*/
  
	stcFilter.enAcfFormat = CanStdFrames;

    stcFilter.enFilterSel = CanFilterSel1;
    stcFilter.u32CODE     = CAN_ID_BACKLIGHT;
    stcFilter.u32MASK     = 0x1FFFFFFF& (~CAN_ID_BACKLIGHT);   
    CAN_FilterConfig(&stcFilter, TRUE);
 
	stcFilter.enFilterSel = CanFilterSel2;
    stcFilter.u32CODE     = CAN_ID_ACC;
    stcFilter.u32MASK     = 0x1FFFFFFF& (~CAN_ID_ACC);
	CAN_FilterConfig(&stcFilter, TRUE); 
	
	stcFilter.enFilterSel = CanFilterSel3;
    stcFilter.u32CODE     = CAN_ID_BRAKE_X;
    stcFilter.u32MASK     = 0x1FFFFFFF& (~CAN_ID_BRAKE_X);
    CAN_FilterConfig(&stcFilter, TRUE);
 
	stcFilter.enFilterSel = CanFilterSel4;
	stcFilter.u32CODE     = CAN_ID_BRAKE_SIGNAL;
	stcFilter.u32MASK     = 0x1FFFFFFF& (~CAN_ID_BRAKE_SIGNAL);
	CAN_FilterConfig(&stcFilter, TRUE);
 
    CAN_IrqCmd(CanRxIrqEn, TRUE); /* 接收中断使能 */
	CAN_IrqCmd(CanBusErrorIrqEn, TRUE); /*总线错误中断使能*/
    EnableNvic(CAN_IRQn, IrqLevel0, TRUE);
}


/********************************************************************************************************
**函数信息 ：void CAN_send_Frame()
**功能描述 ：CAN发送一帧报文
**输入参数 ：stcTxFrame
**输出参数 ：None
**    备注  目前只考虑标准帧
********************************************************************************************************/
void CAN_send_Frame(stc_can_txframe_t *TxFrame, uint8_t frame_len)
{
	TxFrame->Control_f.DLC = frame_len;
	TxFrame->Control_f.IDE = 0; /*标准帧 or 扩展帧*/
	TxFrame->Control_f.RTR = 0; /*数据帧 or 远程帧*/
	TxFrame->enBufferSel = (en_can_buffer_sel_t)0U; /*使用主缓冲器*/
	CAN_SetFrame(TxFrame); /*数据塞进fifo缓冲器*/	
	CAN_TransmitCmd(CanPTBTxCmd);
}
	

void Can_IRQHandler(void)
{
    if(TRUE == CAN_IrqFlgGet(CanBusErrorIrqFlg))  /*当总线短路时,进入此中断*/
	{	  
		CAN_IrqFlgClr(CanBusErrorIrqFlg);	 
		APP_CAN.BusErrorFlag = TRUE;
		// M0P_CAN->CFG_STAT = 0x00; /* 清除由硬件置位的Reset 标志位,必须在中断外部执行*/		 
	}	 
	if(TRUE == CAN_IrqFlgGet(CanRxIrqFlg))
    {
        CAN_IrqFlgClr(CanRxIrqFlg);
        CAN_Receive(&stcRxFrame);
		APP_CAN.RxFlag = TRUE;
		APP_CAN.Rx_cnt = 0;
		/*总线上发送周期约500ms*/
		if( CAN_ID_BACKLIGHT == stcRxFrame.StdID )
		{
		/*			
		led off  3b3 40 48 00 12 10 05 80 02
		led on	 3b3 44 48 10 12 10 05 80 02
		*/
			if(stcRxFrame.Data[0] & 0x04)
			{
				LED_ON;
			}	
			else
			{
				LED_OFF;
			}
		}
		/*
		XX 00 00 20 52 FF FB 00
		XX:02 (ON)  00(OFF)
		*/	
		if (CAN_ID_ACC == stcRxFrame.StdID)
		{
			if(stcRxFrame.Data[0]&0x02)
			{
				ACC_Status = On;
			}
			else
			{			
				ACC_Status = Off;  /* ACC off 后延时30s进入休眠*/			
			}
		}
		/*
		ID:7D(刹车深度)  //20ms一次
		XX YY 00 00 00 00 00 00 
		XX:刹车深度高位
		YY:刹车深度低位
		XX<<8+YY = 0000 表示无刹车，最大到0F00(超级用力)	
		*/
		if (CAN_ID_BRAKE_X == stcRxFrame.StdID) /* 刹车深度,最后与滑动变阻器比较，谁力度大则执行pwm输出*/
		{
			APP_CAN.brake_value = (stcRxFrame.Data[0]<<8) + stcRxFrame.Data[1];		
			// 按等比例换算,再和adc_value 比较，再执行
			APP_CAN.RxFlag_Break = TRUE;
			
		}
		/*
		ID:242(刹车信号)   //40ms一次
		00 00 xx 00 00 00 00 00
		xx：80（有踩刹车） 00（无踩刹车）
		*/	
		if (CAN_ID_BRAKE_SIGNAL == stcRxFrame.StdID)
		{		
			if( stcRxFrame.Data[2]&0x80)
			{
				APP_CAN.brake_signal = TRUE;
			}
			else
			{			
				APP_CAN.brake_signal = FALSE;
			}
		}		
    }
}

